package cn.coastalinfo.project.drools.service.impl;

import cn.coastalinfo.project.drools.domain.Rule;
import cn.coastalinfo.project.drools.domain.RuleVariable;
import cn.coastalinfo.project.drools.enums.ConditionType;
import cn.coastalinfo.project.drools.enums.OPeratorType;
import cn.coastalinfo.project.drools.mapper.RuleMapper;
import cn.coastalinfo.project.drools.utils.DroolsRuleUtils;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.coastalinfo.common.utils.TreeBuildUtils;
import cn.coastalinfo.project.drools.domain.bo.RuleBo;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.coastalinfo.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import cn.coastalinfo.project.drools.domain.bo.RuleConditionBo;
import cn.coastalinfo.project.drools.domain.vo.RuleConditionVo;
import cn.coastalinfo.project.drools.domain.RuleCondition;
import cn.coastalinfo.project.drools.mapper.RuleConditionMapper;
import cn.coastalinfo.project.drools.service.IRuleConditionService;

import java.util.*;

/**
 * 规则条件Service业务层处理
 *
 * @author hadge
 * @date 2024-06-08
 */
@RequiredArgsConstructor
@Service
public class RuleConditionServiceImpl extends ServiceImpl<RuleConditionMapper, RuleCondition> implements IRuleConditionService {

    @Autowired
    private RuleConditionMapper baseMapper;

    @Autowired
    private RuleMapper ruleMapper;

    /**
     * 查询规则条件
     */
    @Override
    public RuleConditionVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }


    /**
     * 查询规则条件列表
     */
    @Override
    public List<RuleConditionVo> queryList(RuleConditionBo bo) {
        LambdaQueryWrapper<RuleCondition> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<RuleCondition> buildQueryWrapper(RuleConditionBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<RuleCondition> lqw = Wrappers.lambdaQuery();
                    lqw.eq(bo.getRuleId() != null, RuleCondition::getRuleId, bo.getRuleId());
                    lqw.eq(bo.getParentId() != null, RuleCondition::getParentId, bo.getParentId());
                    lqw.eq(StringUtils.isNotNull(bo.getType()), RuleCondition::getType, bo.getType());
                    lqw.eq(StringUtils.isNotBlank(bo.getLeftType()), RuleCondition::getLeftType, bo.getLeftType());
                    lqw.eq(bo.getLeftId() != null, RuleCondition::getLeftId, bo.getLeftId());
                    lqw.eq(StringUtils.isNotBlank(bo.getLeftValue()), RuleCondition::getLeftValue, bo.getLeftValue());
                    lqw.eq(StringUtils.isNotNull(bo.getOperator()), RuleCondition::getOperator, bo.getOperator());
                    lqw.eq(StringUtils.isNotBlank(bo.getRightType()), RuleCondition::getRightType, bo.getRightType());
                    lqw.eq(bo.getRightId() != null, RuleCondition::getRightId, bo.getRightId());
                    lqw.eq(StringUtils.isNotBlank(bo.getRightValue()), RuleCondition::getRightValue, bo.getRightValue());
        return lqw;
    }

    /**
     * 新增规则条件
     */
    @Override
    public Long insertByBo(RuleConditionBo bo) {
        RuleCondition add = BeanUtil.toBean(bo, RuleCondition.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return add.getId();
    }

    @Override
    public Boolean saveTree(RuleConditionBo bo) {
        RuleCondition add = BeanUtil.toBean(bo, RuleCondition.class);
        if(bo.getId() == null){//删除数据
            Map<String, Object> delp= new HashMap<String, Object>();
            delp.put("rule_id", add.getRuleId());
            baseMapper.deleteByMap(delp);
        }
        baseMapper.insertOrUpdate(add);
        //删除所有子节点
        Map<String, Object> delMap = new HashMap<String, Object>();
        delMap.put("parent_id", add.getId());
        baseMapper.deleteByMap(delMap);
        saveChildren(add);
        //更规则内容
        Rule rule = ruleMapper.selectById(bo.getRuleId());
        rule.setThenSet(bo.getThenSet());
        //更新content
        String lhs = DroolsRuleUtils.contion2LHS(add,new StringBuilder(),0,null,"");
        rule.setContent(DroolsRuleUtils.rule2Drl(rule,lhs));
        ruleMapper.updateById(rule);
        return true;
    }

    @Override
    public Boolean saveChildren(RuleCondition ruleCondition) {
        if (ruleCondition.getChildren() != null) {
            for (RuleCondition child : ruleCondition.getChildren()) {
                child.setId(null);
                child.setParentId(ruleCondition.getId());
                child.setRuleId(ruleCondition.getRuleId());
                baseMapper.insert(child); // 保存子节点
                saveChildren(child); // 递归插入孙节点，以此类推
            }
        }
        return true;
    }

    @Override
    public RuleCondition treeInfoByRuleId(Long ruleId) {
        RuleConditionBo bo = new RuleConditionBo();
        QueryWrapper<RuleCondition> wrapper = Wrappers.query();
        wrapper.eq("rule_id",ruleId);
        wrapper.eq("parent_id",0);
        RuleCondition ruleCondition = baseMapper.selectOne(wrapper);
        if(ObjectUtil.isNull(ruleCondition)){
            ruleCondition = new RuleCondition();
            ruleCondition.setRuleId(ruleId);
            ruleCondition.setParentId(0L);
            ruleCondition.setType(ConditionType.AND);
            ruleCondition.setOperator(OPeratorType.eq);
            return ruleCondition;
        }
        Rule rule = ruleMapper.selectById(ruleId);
        if(ObjectUtil.isNotNull(rule)){
            ruleCondition.setThenSet(rule.getThenSet());
        }

        wrapper = Wrappers.query();
        wrapper.eq("rule_id",ruleId);
        List<RuleCondition> list = baseMapper.selectList(wrapper);
                return this.findChildren(ruleCondition,list);
//        List<Tree<Long>> treeList = TreeBuildUtils.build(list,(c, tree) ->
//                tree.setId(c.getId())
//                        .setParentId(c.getParentId())
//                        .setName(c.getType().getCode())
//                        .setWeight(c.getId()));
//        if(treeList.isEmpty()){
//            return null;
//        }
//        return treeList.get(treeList.size()-1);
    }

    /**
     * 递归方法
     * @param tree 父节点对象
     * @param treeList 所有的List
     * @return
     */
    private   RuleCondition findChildren(RuleCondition tree, List<RuleCondition> treeList) {
        for (RuleCondition node : treeList) {
            if (tree.getId().equals(node.getParentId())) {
                if (tree.getChildren() == null) {
                    tree.setChildren(new ArrayList<>());
                }
                // 递归 调用自身
                tree.getChildren().add(findChildren(node, treeList));
            }
        }
        return tree;
    }

    /**
     * 修改规则条件
     */
    @Override
    public Long updateByBo(RuleConditionBo bo) {
        RuleCondition update = BeanUtil.toBean(bo, RuleCondition.class);
        validEntityBeforeSave(update);
        baseMapper.updateById(update);
        return update.getId();
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(RuleCondition entity){

    }

    /**
     * 批量删除规则条件
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<RuleVariable> getParams(String groupName) {
        return baseMapper.getParams();
    }

    public int checkRuleNameUnique(RuleBo rule){
        return 0;
    }
}
